package com.timzaak.osl.bugly

import org.json4s.JValue
import ws.very.util.json.JsonHelperWithDoubleMode

import scala.util.Try


//"accessUser": 12972,//联网用户数
//"crashCount": 21,//crash次数
//"crashUser": 20,//crash影响用户数
//"version": "1.2.3",//app版本号
//"url": "http://bugly.qq.com/realtime?app=1104512706&pid=1&ptag=1005-10003&vers=0.0.0.12.12&time=last_7_day&tab=crash"

sealed trait BuglyEntity {
  def timestamp: L

  def appId: S

  def platformId: I

  def date: S

  def appUrl: S

  def signature: S
}

case class BuglyCrashData(accessUser: L, crashUser: L, crashCount: L, version: S, url: S)


//"appId": "1104512706", //appId
//"platformId": 1   //平台
//"appName": "AF", //app名称
//"date": "20160508",
//"appUrl":"http://bugly.qq.com/issueIndex?app=1104512706&pid=1&ptag=1005-10000"
case class BuglyCrash(appId: S,
                      platformId: I,
                      date: S,
                      appUrl: S,
                      datas: Seq[BuglyCrashData],
                      signature: S,
                      timestamp: L) extends BuglyEntity {

}

//"tagId": 12972, //tagId
//"tagName": "testTag2", //tag名称
//"crashCount": 21,//crash次数
//"crashUser": 20,//crash用户数
//"type": 2     //tag类型,1为sdk上设置上报,2为页面手动设置
//"url": "http://bugly.qq.com/search?app=1104512706&pid=1&ptag=1017-10000&ver=all&bi=all&cl=all&ct=all&s=all&dt=all&tl=12972"
case class BuglyTagData(tagId: I, tagName: S, crashCount: L, crashUser: L, `type`: I, url: S)


//"appId": "1104512706",
//"platformId": 1
//"appName": "AF", //app名称
//"date": "20160508",
case class BuglyTag(
                     appId: S,
                     platformId: I,
                     date: S,
                     appUrl: S,
                     datas: Seq[BuglyTagData],
                     signature: S,
                     timestamp: L
                   ) extends BuglyEntity

object BuglyEntity extends JsonHelperWithDoubleMode {


  import JsonExtractors._

  val Array(jEventType, jTimestamp, jAppId, jPlatformId, jAppName, jDate, jSignature,
  jEventContent, jAppUrl, jdatas) = Array(
    "eventType", "timestamp", "appId", "platformId", "appName", "date", "signature",
    "eventContent", "appUrl", "datas"
  ).map(param)

  val Array(jAccessUser, jCrashCount, jVersion, jUrl) = Array(
    "accessUser", "crashCount", "version", "url"
  ).map(param)


  val Array(jTagId, jTagName, jCrashUser, jType) = Array(
    "tagId", "tagName", "crashUser", "type"
  ).map(param)

  private val jBuglyTagData = { (message: JValue) =>
    Try {
      message match {
        case jTagId(int(tagId)) & jTagName(int(tagName)) & jCrashCount(int(crashCount))
          & jCrashUser(int(crashUser)) & jType(int(typz)) & jUrl(url) =>
          BuglyTagData(tagId, tagName, crashCount, crashUser, typz, url)
      }
    }.toOption
  }.toCase

  private val jBuglyTagDatas = array.toPfn[JValue].andThen {
    _.collect {
      jBuglyTagData.toPfn[JValue]
    }
  }.lift.toCase

  //  "accessUser": 12972,//联网用户数
  //  "crashCount": 21,//crash次数
  //  "crashUser": 20,//crash影响用户数
  //  "version": "1.2.3",//app版本号
  //  "url":
  private val jBuglyCrashData = { (message: JValue) =>
    Try {
      message match {
        case jAccessUser(int(accessUser)) & jCrashCount(int(crashCount)) &
          jCrashUser(int(crashUser)) & jVersion(str(version)) & jUrl(str(url)) =>
          BuglyCrashData(accessUser, crashUser, crashCount, version, url)
      }
    }.toOption
  }.toCase

  private val jBuglyCrashDatas = array.toPfn[JValue].andThen {
    _.collect {
      jBuglyCrashData.toPfn[JValue]
    }
  }.lift.toCase

  def apply(message: JValue) = {
    Try {
      message match {
        case jEventType(str("bugly_tag")) & jTimestamp(int(timestamp)) & jSignature(str(signature))
          & jEventContent(jdatas(jBuglyTagDatas(buglyTagDatas)) & jAppId(str(appId)) & jPlatformId(int(platformId))
          & jAppName(str(appName)) & jDate(str(date))
          & jAppUrl(str(appUrl))) =>
          BuglyTag(appId, platformId, date, appUrl, buglyTagDatas, signature, timestamp)

        case jEventType(str("bugly_crash_trend"))& jSignature(str(signature))& jTimestamp(int(timestamp))
          & jEventContent(jdatas(jBuglyCrashDatas(crashDatas)) & jAppId(str(appId)) & jPlatformId(int(platformId))
          & jAppName(str(appName)) & jDate(str(date))
          & jAppUrl(str(appUrl))) =>
          BuglyCrash(appId, platformId, date, appUrl, crashDatas, signature, timestamp)

      }
    }
  }
}

object _Test extends App with JsonHelperWithDoubleMode {
  val crashTrend =
    """
      |{
      |  "eventType": "bugly_crash_trend",
      |  "timestamp": 1462780713515,
      |  "isEncrypt": 0,
      |  "eventContent": {
      |    "datas": [
      |      {
      |        "accessUser": 12972,
      |        "crashCount": 21,
      |        "crashUser": 20,
      |        "version": "1.2.3",
      |        "url": "http://bugly.qq.com/realtime?app=1104512706&pid=1&ptag=1005-10003&vers=0.0.0.12.12&time=last_7_day&tab=crash"
      |      },
      |      {
      |        "accessUser": 15019,
      |        "crashCount": 66,
      |        "crashUser": 64,
      |        "version": "1.2.4",
      |        "url": "http://bugly.qq.com/realtime?app=1104512706&pid=1&ptag=1005-10003&vers=0.0.0.12.12&time=last_7_day&tab=crash"
      |      },
      |      {
      |        "accessUser": 15120,
      |        "crashCount": 1430,
      |        "crashUser": 1423,
      |        "version": "1.2.4",
      |        "url": "http://bugly.qq.com/realtime?app=1104512706&pid=1&ptag=1005-10003&vers=0.0.0.12.12&time=last_7_day&tab=crash"
      |      }
      |    ],
      |    "appId": "1104512706",
      |    "platformId": 1,
      |"appName": "AF",
      |    "date": "20160508",
      |"appUrl":"http://bugly.qq.com/issueIndex?app=1104512706&pid=1&ptag=1005-10000"
      |  },
      |  "signature": "ACE346A4AE13A23A52A0D0D19350B466AF51728A"
      |}
    """.stripMargin

  val jsonCrash = parseJson(crashTrend)
  assert(BuglyEntity(jsonCrash).isSuccess, "jsonCrash解析错误")

  val tag =
    """
      |{
      |  "eventType": "bugly_tag",
      |  "timestamp": 1462780713515,
      |  "isEncrypt": 0,
      |  "eventContent": {
      |    "datas": [
      |      {
      |        "tagId": 12972,
      |        "tagName": "testTag2",
      |        "crashCount": 21,
      |        "crashUser": 20,
      |        "type": 2,
      |        "url": "http://bugly.qq.com/search?app=1104512706&pid=1&ptag=1017-10000&ver=all&bi=all&cl=all&ct=all&s=all&dt=all&tl=12972"
      |      },
      |      {
      |        "tagId": 15019,
      |        "tagName": "testTag1",
      |        "crashCount": 66,
      |        "crashUser": 64,
      |        "type": 2
      |        "url": "http://bugly.qq.com/search?app=1104512706&pid=1&ptag=1017-10000&ver=all&bi=all&cl=all&ct=all&s=all&dt=all&tl=12972"
      |      },
      |      {
      |        "tagId": 15120,
      |        "tagName": "testTag",
      |        "crashCount": 1430,
      |        "crashUser": 1423,
      |        "type": 2
      |        "url": "http://bugly.qq.com/search?app=1104512706&pid=1&ptag=1017-10000&ver=all&bi=all&cl=all&ct=all&s=all&dt=all&tl=12972"
      |      }
      |    ],
      |    "appId": "1104512706",
      |    "platformId": 1
      |    "appName": "AF",
      |    "date": "20160508",
      |    "appUrl":"http://bugly.qq.com/issueIndex?app=1104512706&pid=1&ptag=1005-10000"
      |  },
      |  "signature": "ACE346A4AE13A23A52A0D0D19350B466AF51728A"
      |}
    """.stripMargin
  val tagJson = parseJson(tag)
  assert(BuglyEntity(jsonCrash).isSuccess, "tagJson解析错误")

}